<?php


namespace App\Jobs;


use App\Libraries\CustomsBills\Data\CEB311Message;
use App\Libraries\CustomsBills\Message;
use App\Libraries\Warehouse\Docking;
use App\Libraries\Warehouse\Strategies\GetProduct;
use App\Models\Order;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Throwable;

class DeclareOrder implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    /**
     * @var Order
     * @author luffyzhao@vip.126.com
     */
    private $order;

    /**
     * Create a new job instance.
     *
     * @param Order $order
     */
    public function __construct(Order $order)
    {
        $this->order = $order;
    }

    /**
     * @throws Throwable
     * @author luffyzhao@vip.126.com
     */
    public function handle()
    {
        $this->order->loadMissing(['orderProducts']);
        try{
            $this->declareOrder();
        }catch (Throwable | Exception $exception){
            Log::error('申报订单失败：'. $exception->getMessage());
        }
    }

    /**
     * @author luffyzhao@vip.126.com
     */
    protected function declareOrder()
    {
        $message311 = tap(new CEB311Message(), function (CEB311Message $item) {
            $item->setOrderNo($this->order->getAttribute('order_code'));
            $item->setGoodsValue($this->order->getAttribute('goods_value'));
            $item->setTaxTotal($this->order->getAttribute('tax'));
            $item->setFreight($this->order->getAttribute('freight'));
            $item->setDiscount($this->order->getAttribute('discount'));
            $item->setActuralPaid($this->order->getAttribute('payment'));
            $item->setEbcCode('');
            $item->setEbcName('');
            $item->setEbpCode('');
            $item->setEbpName('');
            $item->setConsigneeTelephone($this->order->getAttribute('receiving_phone'));
            $item->setConsignee($this->order->getAttribute('receiving_name'));
            $item->setConsigneeAddress($this->order->getAttribute('receiving_address'));
            $item->setBuyerRegNo($this->order->getAttribute('buyer_phone'));
            $item->setBuyerIdNumber($this->order->getAttribute('buyer_id_number'));
            $item->setBuyerName($this->order->getAttribute('buyer_name'));
            $item->setBuyerTelephone($this->order->getAttribute('buyer_phone'));

            $this->order->orderProducts->each(function ($value, $key) use ($item){
                $orderList = new CEB311Message\OrderList();
                try{
                    $product = $this->getProduct($value);
                }catch (Exception $exception){
                    throw new Exception(sprintf('获取产品[%s]失败！', $value->sku));
                }

                $orderList->setGnum($key+1);
                $orderList->setPrice($value['price']);
                $orderList->setQty($value['quantity']);

                $orderList->setItemName($value['sku']);
                $orderList->setGModel($product['goodsModel']);
                $orderList->setItemName($product['productName']);
                $orderList->setCountry($product['originCountryCustoms']);
                $orderList->setUnit($product['uom']);

                $item->addOrderList($orderList);
            });
        });

        $message = new Message('CEB311Message');
        $message->addMessageList($message311);

        echo $message->__toString();
    }


    /**
     * @param $item
     * @return mixed
     * @throws Exception
     * @author luffyzhao@vip.126.com
     */
    protected function getProduct($item)
    {
        return Cache::rememberForever('product:' . $item->sku, function () use ($item) {
            $docking = new Docking(new GetProduct([
                'sku' => $item->sku,
                'customerCode' => 'C0399',
                'appToken' => '7470D75F750487B4',
                'appKey' => 'f004a17020787f3dc097bf19208e0579',
            ]));
            return $docking->request();
        });
    }

}